<?php

namespace GanYiInfo;

use GanYiInfo\Http\Response;
use GanYiInfo\HttpClient\Curl;
use GanYiInfo\HttpClient\HttpClientInterface;

class Client
{
    const DEFAULT_REQUEST_TIMEOUT = 60;

    protected $httpClientHandler = null;

    /**
     * PayClient constructor.
     *
     * @param HttpClientInterface|null $httpClientHandler
     * @throws \Exception
     */
    public function __construct(HttpClientInterface $httpClientHandler = null)
    {
        $this->httpClientHandler = is_null($httpClientHandler) ? new Curl() : $httpClientHandler;
    }

    /**
     * Sets the HTTP client handler.
     *
     * @param HttpClientInterface $httpClientHandler
     */
    public function setHttpClientHandler(HttpClientInterface $httpClientHandler)
    {
        $this->httpClientHandler = $httpClientHandler;
    }

    /**
     * Returns the HTTP client handler.
     *
     * @return HttpClientInterface
     */
    public function getHttpClientHandler()
    {
        return $this->httpClientHandler;
    }

    /**
     * Prepares the request for sending to the client handler.
     *
     * @param Request $request
     *
     * @return array
     */
    public function prepareRequestMessage(Request $request)
    {
        $url = $request->getUrl();

        $requestBody = $request->getUrlEncodedBody();
        $request->setHeaders(['Content-Type' => 'application/json']);

        return [$url, $request->getMethod(), $request->getHeaders(), $requestBody->getBody()];
    }

    /**
     * Makes the request to Graph and returns the result.
     *
     * @param Request $request
     *
     * @return Response
     *
     * @throws \Exception
     */
    public function sendRequest(Request $request)
    {
        list($url, $method, $headers, $body) = $this->prepareRequestMessage($request);

        $timeout = static::DEFAULT_REQUEST_TIMEOUT;

        // Should throw `Exception` exception on HTTP client error.
        // Don't catch to allow it to bubble up.
        $rawResponse = $this->httpClientHandler->request($url, $method, $body, $headers, $timeout);
        $returnResponse = new Response($request, $rawResponse);

        return $returnResponse;
    }
}